home *** CD-ROM | disk | FTP | other *** search
- /*
- * name: newlayer
- *
- * description: create a new layer in rectangle r of bitmap *bp
- * and either fill the layer with optional halftone hb
- * or clear it. return a pointer to the new layer.
- *
- * synopsis: struct layer *newlayer (bp, r, hb)
- * struct bitmap *bp;
- * struct rectangle *r;
- * struct bitmap *hb;
- *
- * globals: obs (r/w)
- * endobs (r/w)
- * addpiece () (addpiece.c)
- * toplayer (r/w)
- * bottomlayer (r/w)
- * display (r/w)
- *
- * calls:
- * rectxrect (rectxrect.c)
- * addobs (addobs.c)
- * bfree (bfree.c)
- * free (libc)
- * malloc (libc)
- * layerop (layerop.c)
- * balloc (balloc.c)
- * upfront (upfront.c)
- * bitblt (bitblt.c)
- * rectf (rectf.c)
- *
- * called by: this is a top level function.
- */
- #include "layers.h"
-
- extern struct layer *toplayer;
- extern struct layer *bottomlayer;
- extern struct bitmap *display;
-
- struct obscured *obs;
- struct obscured *endobs;
-
- struct layer *newlayer (bp, r, hb)
- struct bitmap *bp;
- struct rectangle *r;
- struct bitmap *hb; /* optional half tone to fill layer */
- {
- struct layer *lp;
- struct layer *newlp;
- struct obscured *op;
- struct obscured *nop;
-
- int addpiece ();
- struct bitmap *balloc ();
- char *malloc ();
-
- /*
- * first build, in obs, a list of all obscured rectangles that
- * will be obscured by the new layer, doing subdivision with
- * addobs()
- */
- obs = null;
- endobs = null;
- for (lp = toplayer; lp != null; lp = lp -> ly_back) {
- /* lp = each layer from front to back */
- for (op = lp -> ly_obs; op != null;) {
- /* op = each obscured portion of lp */
- nop = op;
- op = op -> ob_next;
- if (rectxrect (r, &(nop -> ob_rect)) &&
- addobs (nop, &(nop -> ob_rect), r, lp)) {
- /*
- * unlink nop from lp -> obs
- */
- if (nop -> ob_prev != null)
- nop -> ob_prev -> ob_next = nop -> ob_next;
- else
- lp -> ly_obs = nop -> ob_next;
- if (nop -> ob_next != null)
- nop -> ob_next -> ob_prev = nop -> ob_prev;
- else
- lp -> ly_endobs = nop -> ob_prev;
- (void) bfree (nop -> ob_bmap);
- free ((char *) nop);
- }
- }
- }
- /*
- * now add the rectangles not currently obscured, but that will
- * be obscured by the new layer, by building the layer and
- * calling layerop()
- */
- /*
- * newlp = new layer
- */
- newlp = (struct layer *) malloc ((unsigned) sizeof (struct layer));
- /*
- * bitmap part of newlp = bp
- */
- newlp -> ly_base = bp -> bm_base; /* to be perfectly frank, */
- newlp -> ly_width = bp -> bm_width; /* i don't understand what */
- /* these are used for */
- newlp -> ly_rect.origin.x = r -> origin.x;
- newlp -> ly_rect.origin.y = r -> origin.y;
- newlp -> ly_rect.corner.x = r -> corner.x;
- newlp -> ly_rect.corner.y = r -> corner.y;
- newlp -> ly_obs = obs; /* currently obscured ... */
- newlp -> ly_endobs = endobs;
- for (lp = toplayer; lp != null; lp = lp -> ly_back)
- /* lp = each layer from front to back */
- (void) layerop (newlp, addpiece, &(lp -> ly_rect), lp, null, null, null);
- newlp -> ly_obs = obs; /* ... and soon to be */
- newlp -> ly_endobs = endobs;
- for (op = obs; op != null; op = op -> ob_next)/* op = each element of obs */
- op -> ob_bmap = balloc (&(op -> ob_rect));
- /*
- * link newlp into back of layer list
- */
- if (bottomlayer != null)
- bottomlayer -> ly_back = newlp;
- else /* first layer */
- toplayer = newlp;
- newlp -> ly_front = bottomlayer;
- newlp -> ly_back = null;
- bottomlayer = newlp;
- (void) upfront (newlp);
- if (hb != null)
- (void) bitblt (null, &(newlp -> ly_rect), display, &(newlp -> ly_rect.origin), hb, s);
- else
- (void) rectf (display, &(newlp -> ly_rect), clr);
- /* clear the screen rectangle */
- return (newlp);
- }